local length = 128
local height = 2
local position = 0
local returnTurtle = true
local torchSpacing = 8
local torchDisabled = 0
local torchRight = 1
local torchLeft = 2
local torchBothSides = 3
local torchMode = 1
local lastTorch = torchSpacing
local removeObstacles = true
local fuelSlot = 1
local refuelingTurtle = "Low fuel detected, refueling"
local outOfFuel = "Turtle out of fuel, waiting for refuel"
local tunnelCompleted = "Tunnel digging completed"
local turtleReturning = "Turtle returning to start"
local turtleReturned = "Turtle returned to start position"
local obstacleEncountered = "Obstacle encountered, waiting"
local author = "Kevin Scroggins"
local nickname = "nitro glycerine"
local email = "nitro404@gmail.com
local website = "http://www.nitro404.com"

function checkFuel()
  if turtle.getItemCount(fuelSlot) == 0 then
    print(outOfFuel)
    
    while turtle.getItemCount(fuelSlot) == 0 do
      os.sleep(1)
    end
  end
  
  if turtle.getFuelLevel() < 15 then
    print(refuelingTurtle)
    turtle.select(fuelSlot)
    if turtle.refuel(1) ~= true then
      print(outOfFuel)
      
      while turtle.refuel(1) ~= true do
        os.sleep(1)
      end
    end
    
    checkFuel()
  end
end

function forward(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.forward() ~= true then
      print(obstacleEncountered)
      
      while turtle.forward() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.dig()
        end
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function back(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.back() ~= true then
      print(obstacleEncountered)
      
      while turtle.back() ~= true do
        checkFuel()
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function up(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.up() ~= true then
      print(obstacleEncountered)
      
      while turtle.up() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.digUp()
        end
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function down(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.down() ~= true then
      print(obstacleEncountered)
      
      while turtle.down() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.digDown()
        end
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function left(n)
  if n == nil then
    n = 1
  elseif n < 1 then
    return
  end
  
  for i = 0, n - 1, 1 do
    turtle.turnLeft()
  end
end

function right(n)
  if n == nil then
    n = 1
  elseif n < 1 then
    return
  end
  
  for i = 0, n - 1, 1 do
    turtle.turnRight()
  end
end

function digTop()
  if position > 1 then
    turtle.dig()
  end
  
  if height > 3 then
    turtle.digUp()
    
    while turtle.detectUp() == true do
      turtle.digUp()
    end
  end
  
  if position > 1 then
    checkFuel()
    
    while turtle.forward() ~= true do
      checkFuel()
      
      turtle.dig()
      
      os.sleep(0.5)
    end
  end
  
  position = position - 1
  
  return true
end

function returnToStart()
  turtle.turnRight()
  turtle.turnRight()
  
  while position > 1 do
    forward()
    
    position = position - 1
  end
  
  return true
end

function digBackToStart()
  turtle.turnLeft()
  turtle.turnLeft()
  while turtle.detectUp() do
    turtle.digUp()
  end
  checkFuel()
  while turtle.up() ~= true do
    checkFuel()
    turtle.digUp()
  end
  turtle.digUp()
  while turtle.detectUp() do
    turtle.digUp()
  end
  checkFuel()
  while turtle.up() ~= true do
    checkFuel()
    turtle.digUp()
  end
  
  while position > 0 do
    digTop()
  end
  
  return true
end

function placeTorch()
  if torchMode == torchRight then
    up()
    turtle.turnRight()
    turtle.dig()
    os.sleep(0.5)
    while turtle.detect() do
      turtle.dig()
      os.sleep(0.5)
    end
    turtle.select(2)
    turtle.place()
    down()
    turtle.turnLeft()
  end
  
  if torchMode == torchLeft then
    up()
    turtle.turnLeft()
    turtle.dig()
    os.sleep(0.5)
    while turtle.detect() do
      turtle.dig()
      os.sleep(0.5)
    end
    turtle.select(2)
    turtle.place()
    down()
    turtle.turnRight()
  end
  
  if torchMode == torchBothSides then
    up()
    turtle.turnRight()
    turtle.dig()
    os.sleep(0.5)
    while turtle.detect() do
      turtle.dig()
      os.sleep(0.5)
    end
    turtle.select(2)
    turtle.place()
    turtle.turnRight()
    turtle.turnRight()
     turtle.dig()
    os.sleep(0.5)
    while turtle.detect() do
      turtle.dig()
      os.sleep(0.5)
    end
    turtle.select(2)
    turtle.place()
    turtle.turnRight()
    down()
  end
end

function checkTorch()
  if torchMode == torchDisabled then
    return false
  end
  
  if lastTorch >= torchSpacing + 1 then
    lastTorch = 0
    return true
  else
    lastTorch = lastTorch + 1
    return false
  end
end

function dig()
  turtle.dig()
  while turtle.detect() do
    turtle.dig()
  end
  
  if position > 0 then
    if height > 1 then
      turtle.digUp()
    end
    
    if position > 1 then
      if checkTorch() == true then
        placeTorch()
      end
    end
  end
  
  checkFuel()
  
  while turtle.forward() ~= true do
    turtle.dig()
    os.sleep(0.5)
  end
  
  position = position + 1
  
  return true
end

function digTunnel()
  write("Digging tunnel ")
  write(length)
  write(" long and ")
  write(height)
  write(" high\n")
  
  while position <= length do
    if dig() ~= true then
      return false
    end
  end
  
  if height > 1 then
    turtle.digUp()
  end
  
  if height < 3 then
    print(tunnelCompleted)
    
    if returnTurtle == true then
      print(turtleReturning)
      if returnToStart() == true then
        turtle.turnRight()
        turtle.turnRight()
        back()
        
        print(turtleReturned)
      end
    end
  else
    if digBackToStart() == true then
      print(tunnelCompleted)
    end
    
    if returnTurtle == true then
      print(turtleReturning)
      
      turtle.turnRight()
      turtle.turnRight()
      down()
      down()
      back()
      
      print(turtleReturned)
    end
  end
end

digTunnel()

